//
//  UIViewController.swift
//  MyLibrary
//
//  Created by 周博 on 2020/6/18.
//  Copyright © 2020 ncit. All rights reserved.
//

import UIKit

private var UIViewController_oldBackGestureDelegate_key: String = "UIViewController_oldBackGestureDelegate_key"

private var UIViewController_leftBackButton_key: String = "UIViewController_leftBackButton_key"

private var UIViewController_leftBackImageName_key: String = "UIViewController_leftBackImageName_key"

private var UIViewController_showBackButton_key: String = "UIViewController_showBackButton_key"

public extension UIViewController {

    /// 自定义navigationBar返回按钮, 手势代理的处理
    var oldBackGestureDelegate: UIGestureRecognizerDelegate? {
        get {
            if let oldBackGestureDelegate = objc_getAssociatedObject(self, &UIViewController_oldBackGestureDelegate_key) as? UIGestureRecognizerDelegate {
                return oldBackGestureDelegate
            } else {
                return nil
            }
        }
        set{
            objc_setAssociatedObject(self, &UIViewController_oldBackGestureDelegate_key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

//    /// 左侧返回按钮 (自定义按钮内容和ContentInset)
//    var backButton: UIButton? {
//        get {
//            if let leftBackButton = objc_getAssociatedObject(self, &UIViewController_leftBackButton_key) as? UIButton {
//                return leftBackButton
//            } else {
//                return nil
//            }
//        }
//        set {
//            objc_setAssociatedObject(self, &UIViewController_leftBackButton_key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
//
//            if let leftBtn = backButton {
//                self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: leftBtn)
//            }
//        }
//    }

    /// 左侧返回按钮 (纯图片)
    var backImageName: String? {
        get {
            if let imageName = objc_getAssociatedObject(self, &UIViewController_leftBackImageName_key) as? String {
                return imageName
            } else {
                return nil
            }
        }
        set {
            objc_setAssociatedObject(self, &UIViewController_leftBackImageName_key, newValue, .OBJC_ASSOCIATION_COPY)

            guard let backImageName = backImageName else {
                return
            }

            let backButton = UIButton(type: .custom)
            backButton.setImage(backImageName.image, for: .normal)
            backButton.addTarget(self, action: #selector(backButtonAction), for: .touchUpInside)

            // 可以不指定frame, 自适应图片, 但是如果图片比较小, 点击比较费事, 如果指定宽度, 那么内容默认居中会导致距离左边比较大, 设置contentEdgeInsets解决
            backButton.frame = CGRect(x: 0, y: 0, width: 60, height: 40)

            // 通过这个属性控制返回按钮内容偏移
            backButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: -40, bottom: 0, right: 0)
            let backItem = UIBarButtonItem(customView: backButton)
            self.navigationItem.leftBarButtonItem = backItem
        }
    }

    /// 是否显示返回按钮
    private var showBackButton: Bool {
        get {
            return objc_getAssociatedObject(self, &UIViewController_showBackButton_key) as! Bool
        }
        set {
            objc_setAssociatedObject(self, &UIViewController_showBackButton_key, newValue, .OBJC_ASSOCIATION_ASSIGN)

            if newValue && navigationController?.children.count ?? 0 > 1 {

                self.navigationItem.leftBarButtonItem?.customView?.isHidden = false
                if backImageName == nil {
                    backImageName = backName
                }
            } else {
                self.navigationItem.leftBarButtonItem?.customView?.isHidden = true
            }
        }
    }


    override open class func initRunTime() {

        exchange(originalSelector: #selector(viewDidLoad), swizzledSelector: #selector(exchange_viewDidLoad))
        exchange(originalSelector: #selector(viewWillAppear(_:)), swizzledSelector: #selector(exchange_viewWillAppear(_:)))
        exchange(originalSelector: #selector(viewWillDisappear(_:)), swizzledSelector: #selector(exchange_viewWillDisAppear(_:)))
        
        exchange(originalSelector: #selector(viewDidLayoutSubviews), swizzledSelector: #selector(exchange_viewDidLayoutSubviews))
    }

    @objc private func exchange_viewDidLoad() {

        /** 实际调用顺序是先执行setup, 然后执行viewDidLoad里的方法 */
        exchange_viewDidLoad()
        
        setup()
    }


    @objc private func exchange_viewWillAppear(_ animated: Bool) {

        // 运行时都是先执行exchange_viewWillAppear下面的代码, 再执行本方法  如果想要严格按照顺序, 添加Dispatch.main.async
        exchange_viewWillAppear(animated)

        // 自定义navigationBar, 如果执行了下面的交换delegate, 会导致系统自带的返回手势失效
        // 自定义navigationBar的时候, 什么都不做就可以了, 系统自带的返回手势ok
        if navigationController?.navigationBar.isHidden == false {
            oldBackGestureDelegate = navigationController?.interactivePopGestureRecognizer?.delegate
            navigationController?.interactivePopGestureRecognizer?.delegate = self
            showBackButton = true
        }
    }

    @objc private func exchange_viewWillDisAppear(_ animated: Bool) {
        exchange_viewWillDisAppear(animated)

        if navigationController?.navigationBar.isHidden == false {
            navigationController?.interactivePopGestureRecognizer?.delegate = oldBackGestureDelegate
        }
    }
    
    @objc private func exchange_viewDidLayoutSubviews() {
        exchange_viewDidLayoutSubviews()
    }

    @objc func backButtonAction() {
        if navigationController != nil {
            navigationController?.popViewController(animated: true)
        } else {
            self.dismiss(animated: true, completion: nil)
        }
    }

    /// 用于init控件, viewDidLoad会自动调用
    @objc func setup() {
        self.navigationController?.navigationBar.isHidden = true
//        self.view.backgroundColor = UIColor.init(hexString: "#FF363A43")
    }
}

// MARK: - 适配系统navigation右滑返回 和 tabbar自定义转场手势动画冲突
extension UIViewController: UIGestureRecognizerDelegate {
    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if let count = navigationController?.children.count {
            return count > 1
        } else {
            return false
        }
    }
}



// MARK: - 转场动画扩展

/**
 * modal转场动画扩展
 */
//private var customModalAnimator_UIViewController = "customModalAnimator_UIViewController"
//private var popverAnimator_UIViewController = "popverAnimator_UIViewController"
//
//public extension UIViewController {

//    var customModalAnimator: CustomModalAnimatior {
//        get {
//            if let customModalAnimator = objc_getAssociatedObject(self, &customModalAnimator_UIViewController) as? CustomModalAnimatior {
//                return customModalAnimator
//            } else {
//                let customModalAnimator = CustomModalAnimatior()
//                self.customModalAnimator = customModalAnimator
//                return customModalAnimator
//            }
//        }
//        set {
//            objc_setAssociatedObject(self, &customModalAnimator_UIViewController, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
//        }
//    }
//
//    var popverAnimator: PopoverAnimator {
//        get {
//            if let popverAnimator = objc_getAssociatedObject(self, &popverAnimator_UIViewController) as? PopoverAnimator {
//                return popverAnimator
//            } else {
//
//                // 这里要用popAnimator接一下, 如果直接 return self.popverAnimator 会导致循环引用get
//                // 如果直接返回PopoverAnimator(), 会导致没有set进去, 每次外面调用get 都会得到不同的PopoverAnimator对象
//                let popAnimator = PopoverAnimator()
//                self.popverAnimator = popAnimator
//                return popAnimator
//            }
//        }
//        set {
//            objc_setAssociatedObject(self, &popverAnimator_UIViewController, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
//        }
//    }


//    /**
//     * 功能: 底部弹出一个控制器, 可以自定义present和dismiss的转场动画效果
//     * 局限: 不能弹出一个被navigation包裹的控制器
//     * tips: 如果想要在弹出的控制器上做一些点击跳转的操作, 要通过代理或者block传递出来操作
//     */
//    func bottomPopUpViewController(toVC: UIViewController, animated: Bool = true) {
//
//        /**
//            let popverAnimator = PopoverAnimator()
//            toVC.transitioningDelegate = popverAnimator
//         这样写只能展示present效果, dismiss效果控制不了, 因为transitioningDelegate是个weak指针, 不能长久持有popverAnimator
//         */
//        popverAnimator.popViewHeight = SCREEN_HEIGHT - 100
//        popverAnimator.hasTapAction = true
//        toVC.transitioningDelegate = popverAnimator
//        toVC.modalPresentationStyle = UIModalPresentationStyle.custom
//        self.present(toVC, animated: animated)
//    }
//
//    func customPopUpViewController(toVC: UIViewController, animated: Bool = true) {
//
//        toVC.modalPresentationStyle = .custom
//        toVC.transitioningDelegate = customModalAnimator
//        present(toVC, animated: animated, completion: nil)
//    }
//}
